/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ChatNI;

import common.Message;
import MVC.*;
import common.Fichier;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Observable;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * TCPcom
 * Class in charge of sending the file via TCP
 * It's a View of the ModelMessOut
 * @author Duy Duc, Metangmo
 */

public class TCPcom extends ChatNI implements java.util.Observer{
    
    private ListenTCP listen;
    private ChatController controller;
    private int port;
    private int phase=0;
    private InetAddress destination;
    private File fichier ;

    
    /**
     * Constructor
     * @param port
     *        Destination port of the remote application which allows him to receive the transfered files
     * @param controller
     *        Instance of the ChatController
     */
    public TCPcom(int port, ChatController controller ) {
        
        this.port = port;
        this.controller = controller;
        this.listen= new ListenTCP(controller, port,null);
        listen.start();
    }

    
    /**
     * update:
     * function receives the update from the ModelMessOut and acts depending on the received information
     * @param o
     *        Model observed by TCPcom which is the ModelMessOut
     * @param obj
     *        Sent object from the ModelMessOut to TCPcom  
     */
    @Override
    public void update(Observable o, Object obj) {
        Fichier obj2;
        
        //Phase 0: TCPcom collects the recipient's IP Address from the ModelMessOut
        if(phase == 0){
            this.destination = (InetAddress)obj;
            phase =1;
            
        }
        //Phase 1: TCPcom collects from the ModelMessOut the file for sending to the recipient
        else{
            if (obj instanceof Fichier){
                obj2=(Fichier)obj;
                this.fichier = obj2.getFic();
                try {
                    
                    this.sendFile();
                } catch (IOException ex) {
                    Logger.getLogger(TCPcom.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            
            phase=0;
        }
    }

    
    /**
     * sendFile:
     * function called for a file transfer by the Controller
     * It takes no parameter because the File object is stored in the Model by the Controller
     * at the time of sending the FILETRANSFERACCEPT message
     * @throws IOException 
     */
    public void sendFile() throws IOException {
         
           Socket echoSocket = null;
           echoSocket =  new Socket(this.destination, 7777);
        try {
 
            byte[] mybytearray = new byte[(int) fichier.length()];

            FileInputStream fis = new FileInputStream(fichier);
            BufferedInputStream bis = new BufferedInputStream(fis);

            DataInputStream dis = new DataInputStream(bis);
            dis.readFully(mybytearray, 0, mybytearray.length);

            //handle file send over socket
            OutputStream os = echoSocket.getOutputStream();

            //Sending file name and file size to the server
            DataOutputStream dos = new DataOutputStream(os);
            dos.writeUTF(fichier.getName());
            dos.writeLong(mybytearray.length);
            dos.write(mybytearray, 0, mybytearray.length);
            dos.flush();
        } catch (Exception e) {
            System.err.println("File does not exist!!!");
        } 
    }   
    
    /**
     * stop
     * function stops the execution of the TCP's threads
     * when the button Disconnection of ChatGUI is called
     */
    public void stop() {
        
        listen.interrupt();       
    }
    
      
    @Override
    public void send(Message message) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Message receive() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
    
    
}
